home *** CD-ROM | disk | FTP | other *** search
/ World of Video / World of Video.iso / gfxprograms / boards / retina / rblanker.lha / RBlankers / RSpliner.c < prev    next >
C/C++ Source or Header  |  1995-02-13  |  21KB  |  738 lines

  1. /*
  2.  * RSpliner
  3.  *
  4.  * A screen blanker for the Retina graphics card.
  5.  * By Michael Heinz, 30 March, 1994
  6.  *
  7.  */
  8.  
  9. #include <exec/memory.h>
  10. #include <exec/ports.h>
  11. #include <exec/execbase.h>
  12. #include <graphics/displayinfo.h>
  13. #include <intuition/intuitionbase.h>
  14. #include <intuition/gadgetclass.h>
  15. #include <libraries/commodities.h>
  16. #include <libraries/gadtools.h>
  17. #include <dos/dosextens.h>
  18. #include <dos/dostags.h>
  19. #include <utility/tagitem.h>
  20.  
  21. #include <clib/alib_protos.h>
  22. #include <clib/commodities_protos.h>
  23. #include <clib/dos_protos.h>
  24. #include <clib/exec_protos.h>
  25. #include <clib/gadtools_protos.h>
  26. #include <clib/graphics_protos.h>
  27. #include <clib/intuition_protos.h>
  28. #include <clib/macros.h>
  29. #include <clib/retina_protos.h>
  30. #include <retina/retina.h>
  31.  
  32. #include <string.h>
  33. #include <stdlib.h>
  34.  
  35. #include <pragmas/commodities_pragmas.h>
  36. #include <pragmas/dos_pragmas.h>
  37. #include <pragmas/exec_pragmas.h>
  38. #include <pragmas/gadtools_pragmas.h>
  39. #include <pragmas/graphics_pragmas.h>
  40. #include <pragmas/intuition_pragmas.h>
  41. #include <pragmas/retina_pragmas.h>
  42. #include "blanker.h"
  43.  
  44. UBYTE *VersionString = "$VER: RSpliner 2.0 (By Michael Heinz)";
  45.  
  46. unsigned char color_table[] =
  47. {
  48.     0, 0, 0, 0, 0, 70, 0, 0, 76, 0, 0, 82, 0, 0, 88, 0, 0, 94,
  49.     0, 0, 100, 0, 0, 106, 0, 0, 112, 0, 0, 118, 0, 0, 124, 0, 0, 130,
  50.     0, 0, 136, 0, 0, 142, 0, 0, 148, 0, 0, 154, 0, 0, 160, 0, 0, 166,
  51.     0, 0, 172, 0, 0, 178, 0, 0, 184, 0, 0, 190, 0, 0, 196, 0, 0, 202,
  52.     0, 0, 208, 0, 0, 214, 0, 0, 220, 0, 0, 226, 0, 0, 232, 0, 0, 238,
  53.     0, 0, 244, 0, 0, 250, 0, 0, 255, 4, 0, 255, 8, 0, 255, 12, 0, 255,
  54. 16, 0, 255, 20, 0, 255, 24, 0, 255, 28, 0, 255, 32, 0, 255, 36, 0, 255,
  55. 40, 0, 255, 44, 0, 255, 48, 0, 255, 52, 0, 255, 56, 0, 255, 60, 0, 255,
  56. 64, 0, 255, 68, 0, 255, 72, 0, 255, 76, 0, 255, 80, 0, 255, 84, 0, 255,
  57.     88, 0, 255, 92, 0, 255, 96, 0, 255, 100, 0, 255, 104, 0, 255, 108, 0, 255,
  58.     112, 0, 255, 116, 0, 255, 120, 0, 255, 124, 0, 255, 128, 0, 255, 132, 0, 255,
  59.     136, 0, 255, 140, 0, 255, 144, 0, 255, 148, 0, 255, 152, 0, 255, 156, 0, 255,
  60.     160, 0, 255, 164, 0, 255, 168, 0, 255, 172, 0, 255, 176, 0, 255, 180, 0, 255,
  61.     184, 0, 255, 188, 0, 255, 192, 0, 255, 196, 0, 255, 200, 0, 255, 204, 0, 255,
  62.     208, 0, 255, 212, 0, 255, 216, 0, 255, 220, 0, 255, 224, 0, 255, 228, 0, 255,
  63.     232, 0, 255, 236, 0, 255, 240, 0, 255, 244, 0, 255, 248, 0, 255, 252, 0, 255,
  64.     255, 0, 252, 255, 0, 248, 255, 0, 244, 255, 0, 240, 255, 0, 236, 255, 0, 232,
  65.     255, 0, 228, 255, 0, 224, 255, 0, 220, 255, 0, 216, 255, 0, 212, 255, 0, 208,
  66.     255, 0, 204, 255, 0, 200, 255, 0, 196, 255, 0, 192, 255, 0, 188, 255, 0, 184,
  67.     255, 0, 180, 255, 0, 176, 255, 0, 172, 255, 0, 168, 255, 0, 164, 255, 0, 160,
  68.     255, 0, 156, 255, 0, 152, 255, 0, 148, 255, 0, 144, 255, 0, 140, 255, 0, 136,
  69.     255, 0, 132, 255, 0, 128, 255, 0, 124, 255, 0, 120, 255, 0, 116, 255, 0, 112,
  70.     255, 0, 108, 255, 0, 104, 255, 0, 100, 255, 0, 96, 255, 0, 92, 255, 0, 88,
  71.     255, 0, 84, 255, 0, 80, 255, 0, 76, 255, 0, 72, 255, 0, 68, 255, 0, 64, 255, 0, 60,
  72.     255, 0, 56, 255, 0, 52, 255, 0, 48, 255, 0, 44, 255, 0, 40, 255, 0, 36, 255, 0, 32,
  73.     255, 0, 28, 255, 0, 24, 255, 0, 20, 255, 0, 16, 255, 0, 12, 255, 0, 8, 255, 0, 4,
  74.     255, 0, 0, 255, 4, 0, 255, 8, 0, 255, 12, 0, 255, 16, 0, 255, 20, 0, 255, 24, 0,
  75.     255, 28, 0, 255, 32, 0, 255, 36, 0, 255, 40, 0, 255, 44, 0, 255, 48, 0, 255, 52, 0,
  76. 255, 56, 0, 255, 60, 0, 255, 64, 0, 255, 68, 0, 255, 72, 0, 255, 76, 0,
  77.     255, 80, 0, 255, 84, 0, 255, 88, 0, 255, 92, 0, 255, 96, 0, 255, 100, 0,
  78.     255, 104, 0, 255, 108, 0, 255, 112, 0, 255, 116, 0, 255, 120, 0, 255, 124, 0,
  79.     255, 128, 0, 255, 132, 0, 255, 136, 0, 255, 140, 0, 255, 144, 0, 255, 148, 0,
  80.     255, 152, 0, 255, 156, 0, 255, 160, 0, 255, 164, 0, 255, 168, 0, 255, 172, 0, 255, 176, 0,
  81.     255, 180, 0, 255, 184, 0, 255, 188, 0, 255, 192, 0, 255, 196, 0, 255, 200, 0,
  82.     255, 204, 0, 255, 208, 0, 255, 212, 0, 255, 216, 0, 255, 220, 0, 255, 224, 0,
  83.     255, 228, 0, 255, 232, 0, 255, 236, 0, 255, 240, 0, 255, 244, 0, 255, 248, 0,
  84.     255, 252, 0, 255, 255, 0, 255, 255, 8, 255, 255, 16, 255, 255, 24, 255, 255, 32,
  85.     255, 255, 40, 255, 255, 48, 255, 255, 56, 255, 255, 64, 255, 255, 72, 255, 255, 80,
  86.     255, 255, 88, 255, 255, 96, 255, 255, 104, 255, 255, 112, 255, 255, 120, 255, 255, 128,
  87.     255, 255, 136, 255, 255, 144, 255, 255, 152, 255, 255, 160, 255, 255, 168, 255, 255, 176,
  88.     255, 255, 184, 255, 255, 192, 255, 255, 200, 255, 255, 208, 255, 255, 216, 255, 255, 224,
  89.     255, 255, 232, 255, 255, 240, 255, 255, 248, 255, 255, 255,
  90. };
  91.  
  92. /*
  93.  * A handy request structure for reporting that we've up and died.
  94.  */
  95. struct EasyStruct quitreq =
  96. {
  97.     sizeof(struct EasyStruct),
  98.     0,
  99.     "RSpliner",
  100.     "RSpliner has suffered an untimely demise\ndue to: %s",
  101.     "OK|OK"
  102. };
  103.  
  104. /*
  105.  * Definitions for our Commodity
  106.  */
  107. struct NewBroker NewBroker =
  108. {NB_VERSION, "RSpliner ", NULL,
  109.  "Silly Rabbit, Qix are for Qids!", NBU_NOTIFY | NBU_UNIQUE, COF_SHOW_HIDE,
  110.  0, NULL, 0};
  111.  
  112.  
  113. #define MAX_SPEED     20L
  114. #define MAX_LINES     300L
  115. #define LINE_BUF      512L
  116.  
  117. #define MIN_LINES      10L
  118. #define DEF_LINES     100L
  119. #define DEF_SPEED     10L
  120.  
  121. #define DELTA_V          10L
  122.  
  123. LONG NumLines, Speed;
  124.  
  125. typedef struct {
  126.     unsigned char color;
  127.     int cur_point;
  128.     int last_point;
  129.     int max_points;
  130.     int tic, speed;
  131.     int xv1, yv1, xv2, yv2;
  132.     int point_list[LINE_BUF][4];
  133. } PList;
  134.  
  135. PList plist;
  136.  
  137. /*
  138.  * Definitions for our configuration window
  139.  */
  140.  
  141. struct NewWindow NewBlankerWindow =
  142. {
  143.     80, 16, 0, 0, 0, 1,
  144.     IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW | IDCMP_GADGETDOWN |
  145.     IDCMP_GADGETUP | IDCMP_VANILLAKEY | SLIDERIDCMP | LISTVIEWIDCMP,
  146.     WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH | SIMPLE_REFRESH,
  147.     NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0,
  148.     WBENCHSCREEN
  149. };
  150.  
  151. struct Window *BlankerWindow;
  152.  
  153. #define GID_HIDE          1
  154. #define GID_BLANK         2
  155. #define GID_QUIT          3
  156. #define GID_TIMEOUT       4
  157. #define GID_CLIENT        5
  158. #define GID_LINES          6
  159. #define GID_SPEED         7
  160.  
  161. #define NUM_GADS         7
  162.  
  163. struct VisualInfo *BlankerVisualInfo;
  164. struct Gadget *BlankerGadgets;
  165. struct TextAttr BlankerAttr =
  166. {"topaz.font", TOPAZ_EIGHTY, FS_NORMAL, FPF_ROMFONT};
  167.  
  168. struct NewGadget NewBlankerGadgets[NUM_GADS] =
  169. {16, 101, 48, 12, "_Hide", &BlankerAttr, GID_HIDE, PLACETEXT_IN, NULL, NULL,
  170.  80, 101, 48, 12, "_Blank", &BlankerAttr, GID_BLANK, PLACETEXT_IN, NULL, NULL,
  171.  144, 101, 48, 12, "_Quit", &BlankerAttr, GID_QUIT, PLACETEXT_IN, NULL, NULL,
  172.  136, 5, 66, 12, "Timeout", &BlankerAttr, GID_TIMEOUT, PLACETEXT_LEFT, NULL, NULL,
  173.  136, 21, 66, 12, "Client Timeout", &BlankerAttr, GID_CLIENT, PLACETEXT_LEFT, NULL, NULL,
  174.  136, 53, 66, 12, "Speed    ", &BlankerAttr, GID_SPEED, PLACETEXT_LEFT, NULL, NULL,
  175.  136, 69, 66, 12, "Lines    ", &BlankerAttr, GID_LINES, PLACETEXT_LEFT, NULL, NULL,
  176. };
  177.  
  178. UBYTE BlankerGadgetKinds[NUM_GADS] =
  179. {
  180.     BUTTON_KIND, BUTTON_KIND, BUTTON_KIND, INTEGER_KIND, INTEGER_KIND, SLIDER_KIND,
  181.     SLIDER_KIND,
  182. };
  183.  
  184. struct TagItem ButtonGadgetTags[] =
  185. {GT_Underscore, (ULONG) '_', TAG_DONE, 0L};
  186.  
  187. struct TagItem TimeGadgetTags[] =
  188. {GTIN_Number, 0L, GTIN_MaxChars, 4L, TAG_DONE, 0L};
  189.  
  190. struct TagItem ClientGadgetTags[] =
  191. {GTIN_Number, 0L, GTIN_MaxChars, 2L, TAG_DONE, 0L};
  192.  
  193. struct TagItem SpeedGadgetTags[] =
  194. {GTSL_Level, 0L, GTSL_Min, 1L, GTSL_Max, MAX_SPEED, GTSL_LevelFormat, 0L,
  195.  GTSL_LevelPlace, PLACETEXT_LEFT, GTSL_MaxLevelLen, 2L, GA_RELVERIFY, TRUE,
  196.  TAG_DONE, 0L};
  197.  
  198. struct TagItem LinesGadgetTags[] =
  199. {GTSL_Level, 0L, GTSL_Min, MIN_LINES, GTSL_Max, MAX_LINES, GTSL_LevelFormat, 0L,
  200.  GTSL_LevelPlace, PLACETEXT_LEFT, GTSL_MaxLevelLen, 3L, GA_RELVERIFY, TRUE,
  201.  TAG_DONE, 0L};
  202.  
  203. struct TagItem *BlankerGadgetTagLists[NUM_GADS] =
  204. {
  205.     &ButtonGadgetTags[0],
  206.     &ButtonGadgetTags[0],
  207.     &ButtonGadgetTags[0],
  208.     &TimeGadgetTags[0],
  209.     &ClientGadgetTags[0],
  210.     &SpeedGadgetTags[0],
  211.     &LinesGadgetTags[0],
  212. };
  213.  
  214. void
  215. CloseBlankerWindow(void)
  216. {
  217.     if (BlankerWindow) {
  218.         /*
  219.          * We save the current position of the window
  220.          * so it will re-open in the same place, later.
  221.          */
  222.         NewBlankerWindow.LeftEdge = BlankerWindow->LeftEdge;
  223.         NewBlankerWindow.TopEdge = BlankerWindow->TopEdge;
  224.  
  225.         RemTool(BlankerGadgets);
  226.         RemTool(BlankerVisualInfo);
  227.         RemTool(BlankerWindow);
  228.         BlankerWindow = NULL;
  229.     }
  230. }
  231.  
  232. void
  233. OpenBlankerWindow(void)
  234. {
  235.     struct Gadget *Ptr;
  236.     UWORD Index;
  237.     static char Title[80];
  238.  
  239.     if (BlankerWindow == NULL) {
  240.         strcpy(Title, "RSpliner = <");
  241.         strcat(Title, PopKey);
  242.         strcat(Title, ">");
  243.  
  244.         if (BlankerWindow = OpenWindowTags(&NewBlankerWindow, WA_Title, Title,
  245.                                    WA_AutoAdjust, TRUE, WA_InnerWidth,
  246.                                 212, WA_InnerHeight, 118, TAG_DONE)) {
  247.  
  248.             AddTool(BlankerWindow, CloseWindow, NULL, "Could not open the window.");
  249.  
  250.             if ((BlankerVisualInfo = GetVisualInfo(BlankerWindow->WScreen, TAG_DONE))
  251.                 == NULL) {
  252.                 RemTool(BlankerWindow);
  253.                 return;
  254.             }
  255.             AddTool(BlankerVisualInfo, FreeVisualInfo, 0L,
  256.                     "Couldn't get visual data.");
  257.  
  258.             BlankerGadgets = NULL;
  259.             if ((Ptr = CreateContext(&BlankerGadgets)) == NULL) {
  260.                 RemTool(BlankerVisualInfo);
  261.                 RemTool(BlankerWindow);
  262.                 return;
  263.             }
  264.             AddTool(Ptr, FreeGadgets, 0L, "Couldn't allocate the gadgets.");
  265.  
  266.             /*
  267.              * Here we re-load the gadgets with the current settings. 
  268.              */
  269.             TimeGadgetTags[0].ti_Data = (ULONG) TimeOut;
  270.             ClientGadgetTags[0].ti_Data = (ULONG) ClientTimeOut;
  271.             SpeedGadgetTags[0].ti_Data = (ULONG) Speed;
  272.             SpeedGadgetTags[3].ti_Data = (ULONG) "%2ld";
  273.             LinesGadgetTags[0].ti_Data = (ULONG) NumLines;
  274.             LinesGadgetTags[3].ti_Data = (ULONG) "%3ld";
  275.  
  276.             for (Index = 0L; Index < NUM_GADS; Index++) {
  277.                 NewBlankerGadgets[Index].ng_TopEdge += BlankerWindow->BorderTop;
  278.  
  279.                 NewBlankerGadgets[Index].ng_VisualInfo = BlankerVisualInfo;
  280.                 Ptr = CreateGadgetA((ULONG) BlankerGadgetKinds[Index], Ptr,
  281.                                     &NewBlankerGadgets[Index],
  282.                                     BlankerGadgetTagLists[Index]);
  283.                 if (Ptr == NULL) {
  284.                     CloseBlankerWindow();
  285.                     return;
  286.                 }
  287.                 NewBlankerGadgets[Index].ng_TopEdge -= BlankerWindow->BorderTop;
  288.             }
  289.  
  290.             AddGList(BlankerWindow, BlankerGadgets, 0L, -1L, NULL);
  291.             RefreshGadgets(BlankerGadgets, BlankerWindow, NULL);
  292.             GT_RefreshWindow(BlankerWindow, NULL);
  293.         }
  294.     }
  295.     ScreenToFront(BlankerWindow->WScreen);
  296.     WindowToFront(BlankerWindow);
  297.     ActivateWindow(BlankerWindow);
  298. }
  299.  
  300. WORD __inline
  301. Insure1(WORD val)
  302. {
  303.     return (WORD)((val == 0) ? (WORD)1 : val);
  304. }
  305.  
  306. /*
  307.  * Create the list of points.
  308.  */
  309. void *__regargs
  310. CreateLines(struct RetinaScreen * Screen,
  311.             LONG NumLines, LONG Speed)
  312. {
  313.     int i;
  314.  
  315.     if (!Screen)
  316.         return NULL;
  317.  
  318.     for (i = 0; i < LINE_BUF; i++) {
  319.         plist.point_list[i][0] = -1;
  320.         plist.point_list[i][1] = -1;
  321.         plist.point_list[i][2] = -1;
  322.         plist.point_list[i][3] = -1;
  323.     }
  324.  
  325.     plist.color = 1;
  326.     plist.max_points = NumLines;
  327.     plist.speed = Speed;
  328.     plist.last_point = 0;
  329.     plist.cur_point = NumLines;
  330.     plist.point_list[NumLines][0] = Random(Screen->rs_Width);
  331.     plist.point_list[NumLines][1] = Random(Screen->rs_Height);
  332.     plist.point_list[NumLines][2] = Random(Screen->rs_Width);
  333.     plist.point_list[NumLines][3] = Random(Screen->rs_Height);
  334.     plist.xv1 = Insure1(RAND(DELTA_V));
  335.     plist.yv1 = Insure1(RAND(DELTA_V));
  336.     plist.xv2 = Insure1(RAND(DELTA_V));
  337.     plist.yv2 = Insure1(RAND(DELTA_V));
  338.  
  339.     return (void *)&plist;
  340. }
  341.  
  342. int __inline __regargs
  343. Bound(int l, int *m, int u)
  344. {
  345.     if (*m < l) {
  346.         *m = l;
  347.         return 1;
  348.     }
  349.     if (*m >= u) {
  350.         *m = u - 1;
  351.         return 1;
  352.     }
  353.     return 0;
  354. }
  355.  
  356. /*
  357.  * move the Lines and redraw them 
  358.  */
  359. void __regargs
  360. DrawLines(void *xplist, struct RetinaScreen *rs)
  361. {
  362.     int *pl;
  363.     PList *plist=xplist;
  364.  
  365.     /*
  366.      * If we don't have a screen, don't draw on it! (duh.) 
  367.      */
  368.     if (!rs)
  369.         return;
  370.  
  371.     if (plist->tic) {
  372.         plist->tic--;
  373.         return;
  374.     }
  375.     plist->tic = Insure1(MAX_SPEED - plist->speed);
  376.  
  377.     pl = plist->point_list[plist->cur_point];
  378.  
  379.     Retina_SetAPen(rs, plist->color);
  380.     plist->color++;
  381.     Retina_Line(rs, pl[0], pl[1], pl[2], pl[3]);
  382.  
  383.     plist->cur_point = (plist->cur_point + 1) % LINE_BUF;
  384.  
  385.     plist->point_list[plist->cur_point][0] = pl[0] + plist->xv1;
  386.     plist->point_list[plist->cur_point][1] = pl[1] + plist->yv1;
  387.     plist->point_list[plist->cur_point][2] = pl[2] + plist->xv2;
  388.     plist->point_list[plist->cur_point][3] = pl[3] + plist->yv2;
  389.  
  390.     if (Bound(0, &plist->point_list[plist->cur_point][0], rs->rs_Width)) {
  391.         if (plist->xv1 > 0) {
  392.             plist->xv1 = -Insure1(Random(DELTA_V));
  393.         } else {
  394.             plist->xv1 = Insure1(Random(DELTA_V));
  395.         }
  396.     }
  397.     if (Bound(0, &plist->point_list[plist->cur_point][1], rs->rs_Height)) {
  398.         if (plist->yv1 > 0) {
  399.             plist->yv1 = -Insure1(Random(DELTA_V));
  400.         } else {
  401.             plist->yv1 = Insure1(Random(DELTA_V));
  402.         }
  403.     }
  404.     if (Bound(0, &plist->point_list[plist->cur_point][2], rs->rs_Width)) {
  405.         if (plist->xv2 > 0) {
  406.             plist->xv2 = -Insure1(Random(DELTA_V));
  407.         } else {
  408.             plist->xv2 = Insure1(Random(DELTA_V));
  409.         }
  410.     }
  411.     if (Bound(0, &plist->point_list[plist->cur_point][3], rs->rs_Height)) {
  412.         if (plist->yv2 > 0) {
  413.             plist->yv2 = -Insure1(Random(DELTA_V));
  414.         } else {
  415.             plist->yv2 = Insure1(Random(DELTA_V));
  416.         }
  417.     }
  418.     Retina_SetAPen(rs, 0);
  419.     pl = plist->point_list[plist->last_point];
  420.     if (pl[0] >= 0)
  421.         Retina_Line(rs, pl[0], pl[1], pl[2], pl[3]);
  422.  
  423.     plist->last_point = (plist->last_point + 1) % LINE_BUF;
  424.  
  425. }
  426.  
  427. void
  428. main(LONG argc, UBYTE * argv[])
  429. {
  430.     char **ToolTypes;
  431.     CxObj *Broker, *ObjectList, *Filter;
  432.     struct IntuiMessage *IntMsg;
  433.     CxMsg *BlankerCxMsg;
  434.     LONG ThisTimeOut, TimeUntilBlank, TimeUntilBlack;
  435.     struct RetinaScreen *BlankerScreen = NULL;
  436.     struct MsgPort *ClientPort = NULL;
  437.     int BlankFlag = 0;
  438.  
  439.     /*
  440.      * open our Libraries 
  441.      */
  442.     AddTool(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",
  443.                                                37L), CloseLibrary, 0L,
  444.             "Couldn't open the intuition.library.");
  445.     AddTool(IconBase = OpenLibrary("icon.library", 37L), CloseLibrary, 0L,
  446.             "Couldn't open the icon library.");
  447.     AddTool(CxBase = OpenLibrary("commodities.library", 37L), CloseLibrary, 0L,
  448.             "Couldn't open the commoidities library.");
  449.     AddTool(GadToolsBase = OpenLibrary("gadtools.library", 37L), CloseLibrary, 0L,
  450.             "Couldn't open the gadtools library.");
  451.     AddTool(RetinaBase = (struct _xy_RetinaBase *)OpenLibrary("retina.library", 7L),
  452.             CloseLibrary, 0L, "Couldn't open the Retina library.");
  453.  
  454.     /*
  455.      * get our Arguments 
  456.      */
  457.  
  458.     if (ToolTypes = ArgArrayInit(argc, argv))
  459.         AddTool(ToolTypes, ArgArrayDone, 0L, NULL);
  460.  
  461.     /*
  462.      * get some Signals 
  463.      */
  464.  
  465.     ServerProcess = SysBase->ThisTask;
  466.     if ((bsp_TimerSig = AllocSignal(-1L)) == -1)
  467.         Quit(10, "Could not allocate a signal.");
  468.     AddTool((void *)bsp_TimerSig, FreeSignal, 0L, NULL);
  469.     if ((bsp_InputSig = AllocSignal(-1L)) == -1)
  470.         Quit(10, "Could not allocate a signal.");
  471.     AddTool((void *)bsp_InputSig, FreeSignal, 0L, NULL);
  472.     if ((bsp_ClientSig = AllocSignal(-1L)) == -1)
  473.         Quit(10, "Could not allocate a signal.");
  474.     AddTool((void *)bsp_ClientSig, FreeSignal, 0L, NULL);
  475.  
  476.     /*
  477.      * initialize our Broker = install us as a Commodity 
  478.      */
  479.  
  480.     AddTool(CxPort = CreateMsgPort(), DeleteMsgPortSafely, 0L,
  481.             "Failed to create a port.");
  482.  
  483.     NewBroker.nb_Descr = &VersionString[6];
  484.     NewBroker.nb_Pri = ArgInt(ToolTypes, "CX_PRIORITY", DEF_CX_PRI);
  485.     NewBroker.nb_Port = CxPort;
  486.     AddTool(Broker = CxBroker(&NewBroker, NULL), DeleteCxObjAll, 0L,
  487.             NULL);
  488.  
  489.     /*
  490.      * get Time Out, Client Time Out and Display mode 
  491.      */
  492.  
  493.     TimeOut = ArgIntRange(ToolTypes, "TIMEOUT", 1L, DEF_TIMEOUT, MAX_TIMEOUT);
  494.     ClientTimeOut = ArgIntRange(ToolTypes, "CLIENTTIMEOUT", 1L, DEF_CLIENT_TIMEOUT,
  495.                               MAX_CLIENT_TIMEOUT);
  496.  
  497.     /*
  498.      * get Parameters for Line Movement 
  499.      */
  500.  
  501.     NumLines = ArgIntRange(ToolTypes, "LINES", MIN_LINES, DEF_LINES, MAX_LINES);
  502.     Speed = ArgIntRange(ToolTypes, "SPEED", 1L, DEF_SPEED, MAX_SPEED);
  503.  
  504.     /*
  505.      * install our hot keys 
  506.      */
  507.  
  508.     PopKey = ArgString(ToolTypes, "CX_POPKEY", DEF_POPKEY);
  509.     BlankKey = ArgString(ToolTypes, "BLANKKEY", DEF_BLANKKEY);
  510.  
  511.     if ((Filter = HotKey(PopKey, CxPort, HOTKEY_OPEN_WINDOW)) == NULL)
  512.         Quit(10, "The CX_POPKEY tool type is invalid.");
  513.     else
  514.         AttachCxObj(Broker, Filter);
  515.     if (CxObjError(Filter))
  516.         Quit(10, "Could not link to the commodity list.");
  517.  
  518.     if ((Filter = HotKey(BlankKey, CxPort, HOTKEY_BLANK_SCREEN)) == NULL)
  519.         Quit(10, "The BLANKKEY tool type is invalid.");
  520.     else
  521.         AttachCxObj(Broker, Filter);
  522.     if (CxObjError(Filter))
  523.         Quit(10, "Could not link to the commodity list.");
  524.  
  525.     /*
  526.      * install our "InputHandler" 
  527.      */
  528.  
  529.     ObjectList = CxCustom(BlankerAction, 0L);
  530.     AttachCxObj(Broker, ObjectList);
  531.     if (CxObjError(ObjectList))
  532.         Quit(10, "Could not link to the commodity list.");
  533.  
  534.     (void)ActivateCxObj(Broker, TRUE);
  535.     AddTool(Broker, ActivateCxObj, 0L, "The broker broke.");
  536.  
  537.     /*
  538.      * open Window on startup if not forbidden 
  539.      */
  540.  
  541.     if (stricmp(ArgString(ToolTypes, "CX_POPUP", ""), "NO"))
  542.         OpenBlankerWindow();
  543.  
  544.     /*
  545.      * increase our Priority 
  546.      */
  547.  
  548.     AddTool(FindTask(NULL), SetTaskPri, (LONG) SetTaskPri(FindTask(NULL), SERVER_PRI),
  549.             "Findtask failed!");
  550.  
  551.     /*
  552.      * start the Loop 
  553.      */
  554.  
  555.     TimeUntilBlank = ThisTimeOut = 10L * TimeOut;
  556.     TimeUntilBlack = 10L * ClientTimeOut;
  557.  
  558.     FOREVER
  559.     {
  560.         ULONG Mask;
  561.  
  562.         if (BlankerWindow)
  563.             Mask = Wait(MASK(bsp_TimerSig) | MASK(bsp_InputSig) | MASK(bsp_ClientSig) |
  564.                         MASK(CxPort->mp_SigBit) |
  565.                         MASK(BlankerWindow->UserPort->mp_SigBit) |
  566.                         SIGBREAKF_CTRL_C);
  567.         else
  568.             Mask = Wait(MASK(bsp_TimerSig) | MASK(bsp_InputSig) | MASK(bsp_ClientSig) |
  569.                         MASK(CxPort->mp_SigBit) | SIGBREAKF_CTRL_C);
  570.  
  571.         /*
  572.          * process Window Events 
  573.          */
  574.  
  575.         while ((BlankerWindow != NULL) && (IntMsg =
  576.                                  GT_GetIMsg(BlankerWindow->UserPort)))
  577.             switch (IntMsg->Class) {
  578.                 struct Gadget *Clicked;
  579.                 UWORD Code;
  580.  
  581.             case IDCMP_CLOSEWINDOW:
  582.                 GT_ReplyIMsg(IntMsg);
  583.                 CloseBlankerWindow();
  584.                 break;
  585.             case IDCMP_REFRESHWINDOW:
  586.                 GT_BeginRefresh(BlankerWindow);
  587.                 GT_EndRefresh(BlankerWindow, TRUE);
  588.                 break;
  589.             case IDCMP_GADGETUP:
  590.                 Code = IntMsg->Code;
  591.                 Clicked = (struct Gadget *)IntMsg->IAddress;
  592.                 GT_ReplyIMsg(IntMsg);
  593.                 switch (Clicked->GadgetID) {
  594.                 case GID_HIDE:
  595.                     CloseBlankerWindow();
  596.                     break;
  597.                 case GID_QUIT:
  598.                     Quit(0, "Normal Termination.");
  599.                 case GID_BLANK:
  600.                     if (TimeUntilBlank)
  601.                         TimeUntilBlank = ThisTimeOut = 2L;
  602.                     break;
  603.                 case GID_TIMEOUT:
  604.                     if (GetNum(BlankerWindow, Clicked, 1L, &TimeOut, MAX_TIMEOUT))
  605.                         TimeUntilBlank = ThisTimeOut = 10L * TimeOut;
  606.                     break;
  607.                 case GID_CLIENT:
  608.                     if (GetNum(BlankerWindow, Clicked, 1L, &ClientTimeOut, MAX_CLIENT_TIMEOUT))
  609.                         TimeUntilBlack = 10L * ClientTimeOut;
  610.                     break;
  611.                 case GID_LINES:
  612.                     NumLines = Code;
  613.                     break;
  614.                 case GID_SPEED:
  615.                     Speed = Code;
  616.                     break;
  617.                 }
  618.                 break;
  619.             case IDCMP_VANILLAKEY:
  620.                 Code = IntMsg->Code;
  621.                 GT_ReplyIMsg(IntMsg);
  622.                 switch ((char)Code) {
  623.                 case 'H':
  624.                 case 'h':
  625.                     CloseBlankerWindow();
  626.                     break;
  627.                 case 'Q':
  628.                 case 'q':
  629.                     Quit(0, "Normal Termination.");
  630.                 case 'B':
  631.                 case 'b':
  632.                     if (TimeUntilBlank)
  633.                         TimeUntilBlank = ThisTimeOut = 2L;
  634.                 }
  635.                 break;
  636.             default:
  637.                 GT_ReplyIMsg(IntMsg);
  638.             }
  639.  
  640.         /*
  641.          * process Commodity Messages 
  642.          */
  643.  
  644.         while (BlankerCxMsg = (CxMsg *) GetMsg(CxPort))
  645.             HandleCxMsg(Broker, BlankerCxMsg, &TimeUntilBlank, &ThisTimeOut);
  646.  
  647.         /*
  648.          * check for <CTRL>-C 
  649.          */
  650.  
  651.         if (Mask & SIGBREAKF_CTRL_C)
  652.             Quit(0, "Normal Termination.");
  653.  
  654.         /*
  655.          * Input detected, unblank if necessary 
  656.          */
  657.  
  658.         if (Mask & MASK(bsp_InputSig)) {
  659.             if (BlankFlag) {
  660.                 if (ClientPort)
  661.                     RemTool(ClientPort);
  662.  
  663.                 if (BlankerScreen) {
  664.                     SpritesOn(BlankerScreen);
  665.                     RemTool(BlankerScreen);
  666.                 } else
  667.                     Retina_DisplayOn();
  668.                 BlankFlag = 0;
  669.                 ThisTimeOut = 10L * TimeOut;
  670.             }
  671.             TimeUntilBlank = ThisTimeOut;
  672.         }
  673.         /*
  674.          * client has confirmed that it is still alive 
  675.          */
  676.  
  677.         if (Mask & MASK(bsp_ClientSig)) {
  678.             if (BlankerScreen)
  679.                 Retina_DisplayOn();
  680.             TimeUntilBlack = 10L * ClientTimeOut;
  681.             BlankFlag = 1;
  682.         }
  683.         /*
  684.          * 1/10 sec is over 
  685.          */
  686.  
  687.         if (Mask & MASK(bsp_TimerSig))
  688.             if (TimeUntilBlank) {
  689.                 TimeUntilBlank--;
  690.                 if (TimeUntilBlank == 0L) {        /*
  691.                                                  * Time Out reached,
  692.                                                  * blank * the screen 
  693.                                                  */
  694.                     struct ClientMessage ClientMessage;
  695.  
  696.                     BlankFlag = 1;
  697.                     BlankerScreen = CreateScreen(color_table);
  698.                     if (BlankerScreen)
  699.                         AddTool(BlankerScreen, DestroyScreen, 0L, NULL);
  700.                     else
  701.                         /*
  702.                          * do this if we're completely out of video
  703.                          * memory. 
  704.                          */
  705.                         Retina_DisplayOff();
  706.  
  707.                     ClientMessage.bcm_Screen = BlankerScreen;
  708.                     ClientMessage.bcm_SigMask = 1L << bsp_ClientSig;
  709.                     ClientMessage.bcm_Lines = NumLines;
  710.                     ClientMessage.bcm_Speed = Speed;
  711.  
  712.                     if (ClientPort = CreateBlankerClient(RLinesClientProcess,
  713.                                                     &ClientMessage)) {
  714.                         TimeUntilBlack = 10L * ClientTimeOut;
  715.                         /*
  716.                          * try to start Client 
  717.                          */
  718.                         AddTool(ClientPort, DeleteBlankerClient, 0L, NULL);
  719.                     }
  720.                 }
  721.             } else {
  722.                 if ((BlankerScreen) && (RetinaBase->rb_FirstScreen != BlankerScreen)) {
  723.                     Retina_ScreenToFront(BlankerScreen);
  724.                     SpritesOff(BlankerScreen);
  725.                 }
  726.                 if (TimeUntilBlack) {
  727.                     TimeUntilBlack--;
  728.                     if (TimeUntilBlack == 0L)
  729.                         Retina_DisplayOff();    /*
  730.                                                  * Client Time Out *
  731.                                                  * reached, turn entire
  732.                                                  * * screen black 
  733.                                                  */
  734.                 }
  735.             }
  736.     }
  737. }
  738.